export type EleOfArr<T> = T extends Array<infer E> ? E : never

export type ItemType<T extends object[]> = {
  [K in keyof EleOfArr<T>]: EleOfArr<T>[K]
}

// type T = [{ secondctgyid: string; secctgyname: string }, { secondctgyid: number; thirdctgyid: number; thirdname: string }]

// export type TNumber = T[number]

// export type UnionToFn<U> = U extends any ? (args: U) => void : never
// // type TestUnionToFn = UnionToFn<TNumber>

// //infer I在参数上是交叉类型 在返回值是联合类型
// export type UnionTolntersection<U> = (U extends any ? (args: U) => void : never) extends (args: infer I) => void ? I : never
// type TestUnionTolntersection = UnionTolntersection<TNumber>

export function getSubItemFromArr<T extends ItemType<T>[], K extends keyof EleOfArr<T>>(t: T, ...keys: K[]): Pick<EleOfArr<T>, K>[] {
  return t.map(item => {
    return keys.reduce((pre, _cur, index) => {
      return {
        ...pre,
        [keys[index]]: item[keys[index]]
      }
    }, {})
  }) as Pick<EleOfArr<T>, K>[]
}

export function getOneItemValuesFromArr<T extends ItemType<T>[], K extends keyof EleOfArr<T>, E = EleOfArr<T>>(arr: T, k: K) {
  return arr.map(({ [k]: v }: E) => {
    return v
  })
}

export function getNoReptValuesItem(arr: any[]) {
  const ret: any[] = []
  arr.filter(item => !ret.includes(item) && ret.push(item))
  return ret
}

export function getNoReptItem<T extends ItemType<T>[], K extends keyof EleOfArr<T> = keyof EleOfArr<T>>(arr: T, k: K) {
  const ret: ItemType<T>[] = []
  // 1 获取对象中某个元素的值组成的数组
  const oneItemValues: any[] = getOneItemValuesFromArr(arr, k)

  // 2 对oneItemValues数组去重
  let noRepOneItemValues = getNoReptValuesItem(oneItemValues)
  // 3 对对象去重
  arr.map(item => {
    if (noRepOneItemValues.includes(item[k])) {
      noRepOneItemValues.splice(noRepOneItemValues.indexOf(item[k]), 1)
      ret.push(item)
    }
  })
  return ret
}

// function combine<T extends object[]>(...args: T): UnionTolntersection<T[number]>
// function combine<T extends object[]>(...t: T) {
//   return t.reduce((pre, cur) => {
//     return { ...pre, ...cur }
//   }, {})
// }

/** 合并关联的 */
function commbineRelativeCtgy<T extends ItemType<T>[]>(arr: T, relativeKey: string, relativeValues: any) {
  return arr.map(item => {
    return combine(item, { [relativeKey]: relativeValues })
  })
}

type SecThrCtgyList = {
  secondctgyid: number
  secctgyname: string
  firstctgyId: number
  thirdctgyid: number
  thirdctgyname: string
  secctgyid: number
}[]

// 转化
export default function convert(secThrCtgy: SecThrCtgyList) {
  let secCtgyList = getSubItemFromArr(secThrCtgy, 'secondctgyid', 'secctgyname')
  let noReptSecCtgyList = getNoReptItem(secCtgyList, 'secondctgyid')
  let thrdCtgyList = getSubItemFromArr(secThrCtgy, 'thirdctgyid', 'thirdctgyname', 'secctgyid')
  const relativeSecThrCtgyLst = commbineRelativeCtgy(noReptSecCtgyList, 'thirdctgys', [])

  const lastSecThrCtgyList: typeof relativeSecThrCtgyLst = [] // 最终的二级三级分类保存数组
  type LastSecThrCtgy = EleOfArr<typeof relativeSecThrCtgyLst>
  noReptSecCtgyList.map(noReptSecCtgy => {
    const lastThrdList: typeof thrdCtgyList = []
    thrdCtgyList.forEach(thrdCtgy => {
      if (noReptSecCtgy.secondctgyid === thrdCtgy.secctgyid) {
        lastThrdList.push({
          thirdctgyid: thrdCtgy.thirdctgyid,
          thirdctgyname: thrdCtgy.thirdctgyname,
          secctgyid: thrdCtgy.secctgyid
        })
      }
    })
    const lastSecThrCtgy: LastSecThrCtgy = combine(noReptSecCtgy, {
      thirdctgys: lastThrdList
    })
    lastSecThrCtgyList.push(lastSecThrCtgy)
  })
  console.log(lastSecThrCtgyList)
  return lastSecThrCtgyList
}

// type T = [{ secondctgyid: string }, { secctgyname: string }, { secondctgyid: number }, { thirdctgyid: number }, { thirdctgyname: string }]

// type TNumber = T[number] // 把数组切割成了联合类型

// type UnionToFn<U> = U extends any ? (args: U) => void : never
// type TestUnionToFn = UnionToFn<T[number]>

type UnionTolntersection<U> = (U extends any ? (args: U) => void : never) extends (args: infer I) => void ? I : never
/**
 * TestUnionTolntersection 这里符合条件返回的值会是联合类型
 */
// type TestUnionTolntersection = UnionTolntersection<T[number]>

// 方法重载
function combine<T extends object[]>(...args: T): UnionTolntersection<T[number]>
function combine<T extends object[]>(...t: T) {
  return t.reduce((pre, cur) => {
    return { ...pre, ...cur }
  }, {})
}

// const combineObj = combine({ username: 'wangwu', age: 23 }, { phone: 111 })
